package gpar;

import robocode.control.events.*;
import robocode.control.*;
import robocode.BattleResults;

import gpar.ep.Candidate;
import gpar.io.Io;

/** A class which operates Robocode. 
*
* @author Maarten Inja */
public class RobocodeController implements IBattleListener 
{



    private RobocodeEngine robocodeEngine;

    private BattlefieldSpecification battlefieldSpecification = new BattlefieldSpecification();
    private BattleSpecification battleSpecification;
    private BattleResults[] battleResults;
    private RobotSpecification[] robotSpecification;

    private int nrOfRounds;
    private Program program;

    public RobocodeController (Program program)
    {
	    robocodeEngine = new RobocodeEngine();
        robocodeEngine.addBattleListener(this);
        program.println("RobocodeController with path: " + robocodeEngine.getRobotsDir());
        this.program = program;
    }

    public double evaluateCandidate(Candidate candidate, String opponent)
    { 
	    robotSpecification = robocodeEngine.getLocalRepository();//"sample.SpinBot,sample.SpinBot");
        System.out.printf("nr of robots in specification %d\n", robotSpecification.length);
            //Program.DEFAULT_CLASS_FILE_PATH + candidate.getName() + "," + opponent); 

	    battleSpecification = new BattleSpecification(Program.defaultNumberOfFitnessRounds, 
            battlefieldSpecification, robotSpecification);

	    robocodeEngine.runBattle(battleSpecification);
	    robocodeEngine.waitTillBattleOver();

        if (battleResults == null)
            return 0;

        System.out.println("battle results length: " + battleResults.length);
        double s1 = battleResults[0].getScore();
        double s2 = battleResults[1].getScore(); 
       
        // TODO: find a cool fitnes value here, perhaps some super cool method to make this calculation more dynamic 
        double value = 100 * (1 + ((s1 - s2)/(s1 + s2)));

        return value;
    }


    ////// from IBattleLister ... {{{

    
	public void onBattleCompleted(BattleCompletedEvent e) 
	{
        battleResults = e.getIndexedResults();
	    for (BattleResults br : e.getIndexedResults())
	     	Program.print(br.getTeamLeaderName() + " scored: " + br.getScore() + "\n");    
	    //Program.print("Battle Completed:\n");
	}
	
	public void onBattleError(BattleErrorEvent e) 
	{
	    System.err.print("ERROR: " + e.getError() + "\n");	
	}

	public void onBattleFinished(BattleFinishedEvent e) 
	{
        /*
	    if (e.isAborted())
		    Program.print("aborted!\n");
	    else
		    Program.print("not aborted!\n");
        */
	}

	public void onBattleMessage(BattleMessageEvent e) 
	{
         //Program.print("Battle Message:" + e.getMessage() + "\n");
	}

	public void onBattlePaused(BattlePausedEvent arg0) 
	{

	}

	public void onBattleResumed(BattleResumedEvent arg0) 
	{

	}

	public void onBattleStarted(BattleStartedEvent arg0) 
	{

	}

	public void onRoundEnded(RoundEndedEvent arg0) 
	{
	    //Program.print("round ended\n");
	}

	public void onRoundStarted(RoundStartedEvent arg0) 
	{

	}

	public void onTurnEnded(TurnEndedEvent arg0) 
	{

	}

	public void onTurnStarted(TurnStartedEvent arg0) 
	{

	}
    
    // }}}


}

